﻿using BSKTV.Server.Core;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading;
using System.Windows;
using BSKTV.Util;
using System.Threading.Tasks;
using System.Reflection;
using Wpf.Ui.Contracts;
using Wpf.Ui.Services;
using BSKTV.Server.ViewModel;
using BSKTV.Server.View.Page;

namespace BSKTV.Server
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        private static IServiceCollection services;
        private static IServiceProvider serviceProvider;
        private Mutex mutex;

        protected override void OnStartup(StartupEventArgs e)
        {
            string name = Assembly.GetExecutingAssembly().GetName().Name;
            mutex = new Mutex(true, name, out bool flag);
            if (flag)
            {
                ConfigureServices();

                RegisterErrorHandler();
            }
            else
            {
                var p = ProcessUtil.GetCurrentProcess();
                Win32Util.ShowWindowAsync(p.MainWindowHandle, 1);
                Win32Util.SetForegroundWindow(p.MainWindowHandle);

                Environment.Exit(0);
            }
        }

        private static void ConfigureServices()
        {
            services = new ServiceCollection();

            services.AddScoped<IThemeService, ThemeService>();
            services.AddScoped<ITaskBarService, TaskBarService>();
            services.AddScoped<ISnackbarService, SnackbarService>();
            services.AddScoped<IDialogService, DialogService>();
            services.AddScoped<INavigationService, NavigationService>();
            services.AddScoped<IPageService, PageService>();

            services.AddTransient<HomePage>();

            services.AddScoped<MainViewModel>();
            services.AddTransient<HomeViewModel>();

            serviceProvider = services.BuildServiceProvider();
        }

        public static T GetService<T>() where T : class
        {
            return serviceProvider.GetService(typeof(T)) as T;
        }

        public static IServiceProvider GetProvider()
        {
            return serviceProvider;
        }

        private void RegisterErrorHandler()
        {
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;//UI线程异常
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;//Task线程异常
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject != null)
            {
                if (e.ExceptionObject is Exception ex)
                {
                    LogUtil.Instance.Error(ex);
                }
            }
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            LogUtil.Instance.Error(e.Exception);
            e.SetObserved();
        }

        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            LogUtil.Instance.Error(e.Exception);
            e.Handled = true;
        }
    }
}
